/*******************************************************************************
    文件名称： 
	开发者：孙磊
	开发时间地点：2013.12.3 
	邮箱：zhongyuansunlei@163.com
	版本信息：
		
********************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "nodearray.h"
#include "common.h"

int iinit_nodearray(nodearray **pnarr, int isize)
{
	nodearray* q = NULL;
	node* p = NULL;

	q = (nodearray*)malloc(sizeof(nodearray));
	if(q == NULL) {
		return RC_NOSPACE;
	}
	
	p = (node*)malloc(sizeof(node)*isize);
	if(p == NULL) {
		return RC_NOSPACE;
	}
	
	memset(p, 0, sizeof(sizeof(node)*isize));
	q->m_pbase = p;
	q->m_itotalnum = 0;
	q->m_iarraysize = isize;
	*pnarr = q;
	
	return 0;
}

/*
	
	int iurl_mcp(node*p1, void*p2) 
	{
		char* p = (char*)p2;
		p1->m_pvalue = (void*)malloc(strlen(p)+1);
		if(p1->m_pvalue== NULL)
			return RC_NOSPACE;
		
		strcpy((char*)p1->m_pvalue, p);
		p1->m_pvalue[strlen(p)] = '\0';
		return 0;
	}
*/
node* paddnode_2_nodearray(
	nodearray *pnodearray, 
	void*pvalue, 
	int (*mem_alloc_cp_func)(node*, void*),
	int (*cmp_func)(node*, void*),
	int (*hash_func)(void*)
	)
{
	int ihashvalue =  hash_func(pvalue);
	int icur = (ihashvalue%pnodearray->m_iarraysize);
	node* pcur, *plast;
	pcur = plast = (node*)(&pnodearray->m_pbase[icur]);
	if(pcur->m_pvalue ==NULL) {
		if(mem_alloc_cp_func(pcur, pvalue)) {
			return NULL;
		}
		
		pnodearray->m_itotalnum++;
		return pcur;
	}

	while(pcur) {
		if(cmp_func(pcur, pvalue) == 0) {
			return pcur;
		} else {
			plast = pcur;
			pcur = pcur->m_pnext;
		}
	}
	
	pcur = (node*)malloc(sizeof(node));
	if(pcur == NULL) 
		return NULL;

	memset(pcur, 0 , sizeof(node));
	plast->m_pnext = pcur;
	
	if(mem_alloc_cp_func(pcur, pvalue)) {
		return NULL;
	}
	pnodearray->m_itotalnum++;
	
	return pcur;
}

// 1 -- 新增
// 0 -- 已经存在
// -1 -- 错误
int iaddnode_2_nodearray(
	nodearray *pnodearray, 
	void*pvalue, 
	int (*mem_alloc_cp_func)(node*, void*),
	int (*cmp_func)(node*, void*),
	int (*hash_func)(void*)
	)
{
	int ihashvalue =  hash_func(pvalue);
	int icur = (ihashvalue%pnodearray->m_iarraysize);
	node* pcur, *plast;
	pcur = plast = (node*)(&pnodearray->m_pbase[icur]);
	if(pcur->m_pvalue ==NULL) {
		if(mem_alloc_cp_func(pcur, pvalue)) {
			return -1;
		}
		
		pnodearray->m_itotalnum++;
		return 1;
	}
	
	while(pcur) {
		if(cmp_func(pcur, pvalue) == 0) {
			return 0;
		} else {
			plast = pcur;
			pcur = pcur->m_pnext;
		}
	}
	
	pcur = (node*)malloc(sizeof(node));
	if(pcur == NULL) 
		return -1;

	memset(pcur, 0 , sizeof(node));
	plast->m_pnext = pcur;
	
	if(mem_alloc_cp_func(pcur, pvalue)) {
		return -1;
	}
	pnodearray->m_itotalnum++;
	
	return 1;
}

// 1 -- 已经存在
// 0 -- 不存在
int iexist_in_nodearray(
	nodearray *pnodearray, 
	void*pvalue, 
	int (*cmp_func)(node*, void*),
	int (*hash_func)(void*)
	)
{
	int ihashvalue =  hash_func(pvalue);
	int icur = (ihashvalue%pnodearray->m_iarraysize);
	node* pcur, *plast;
	pcur = plast = (node*)(&pnodearray->m_pbase[icur]);
	if(pcur->m_pvalue ==NULL) {
		
		return 0;
	}
	
	while(pcur) {
		if(cmp_func(pcur, pvalue) == 0) {
			return 1;
		} else {
			plast = pcur;
			pcur = pcur->m_pnext;
		}
	}
	
	return 0;
}

int idelnode_from_nodearray(
	nodearray *pnodearray, 
	void*pvalue, 
	void (*mem_free)(void*),
	int (*cmp_func)(node*, void*),
	int (*hash_func)(void*)
	)
{
	int icur = hash_func(pvalue)%pnodearray->m_iarraysize;
	node* pcur, *plast, *pdel;
	pdel = NULL;
	pcur = plast = (node*)(&pnodearray->m_pbase[icur]);
	
	while(pcur) {
		if(cmp_func(pcur, pvalue) == 0) {
			pdel = pcur;
			break;
		} else {
			plast = pcur;
			pcur = pcur->m_pnext;
		}
	}
	
	if(pdel == NULL) {// 
		return RC_NOTFOUND;
	}
	
	Â
	if(pdel == (&pnodearray->m_pbase[icur])) {
		mem_free(pdel->m_pvalue);
		pdel->m_pvalue = NULL;
		return 0;
	}
	
	//È¹ûÊ×ÖµÄªË£¬¾Í°Ò½ڵãmem_free(pdel->m_pvalue);
	plast->m_pnext = pdel->m_pnext;
	free(pdel);
	
	return 0;
}

void vprint_nodearray(nodearray *pnodearray, void (*print_func)(void*))
{
	int i;
	node* pcur;
	
	for(i=0;i<pnodearray->m_iarraysize;i++) {
		pcur = &pnodearray->m_pbase[i];
		
		while(pcur) {
			print_func(pcur->m_pvalue);
			pcur=pcur->m_pnext;
		}
	}
	
}

int irelease_nodearray(nodearray *pnodearray, void (*mem_free)(void*))
{
	int i;
	node* pcur, *plast;
	
	for(i=0;i<pnodearray->m_iarraysize;i++) {
		pcur = pnodearray->m_pbase[i].m_pnext;
		
		while(pcur) {
			plast = pcur;
			pcur=pcur->m_pnext;
			mem_free(plast->m_pvalue);
			free(plast);
		}
	}
	
	free(pnodearray->m_pbase);
	free(pnodearray);	
	
	return 0;
}



